package example;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.Test;

public class ClassWithThreadingProblemTest {
    int[] generatedIds = new int[2];
    int nextIdStoredIndex;

    private synchronized void rememberIdGenerated(int id) {
        generatedIds[nextIdStoredIndex++] = id;
    }

    @Test
    public void twoThreadsShouldFailEventually() throws Exception {
        final ClassWithThreadingProblem classWithThreadingProblem = new ClassWithThreadingProblem();

        Runnable runnable = new Runnable() {
            public void run() {
                int generatedId = classWithThreadingProblem.takeNextId();
                rememberIdGenerated(generatedId);
            }
        };

        for (int i = 0; i < 10000; ++i) {
            nextIdStoredIndex = 0;
            Thread t1 = new Thread(runnable);
            Thread t2 = new Thread(runnable);
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            assertTrue(Math.abs(generatedIds[0] - generatedIds[1]) == 1);
        }

        fail("This test should have exposed a threading issue but it did not.");
    }

}
